#include "OKIN_drive_pwm.h"
#include <stdbool.h>
#include <stdint.h>
#include "nrf.h"
#include "nrf_drv_timer.h"
#include "bsp.h"
#include "app_error.h"
#include "nrf_log.h"
#include "OKIN_rf_sync.h"
#include "app_error.h"
#include "nrf_delay.h"
#include "app_pwm.h"
#include "board.h"

const nrf_drv_timer_t TIMER_1 = NRF_DRV_TIMER_INSTANCE(1);

APP_PWM_INSTANCE(PWM2,1);                   		// Create the instance "PWM1" using TIMER1.
APP_PWM_INSTANCE(PWM_SPEED,4);                   // Create the instance "PWM1" using TIMER1.

APP_PWM_INSTANCE(PWM_UBB,2);                   // Create the instance "PWM1" using TIMER1.



static volatile bool ready_flag;            // A flag indicating PWM status.

void pwm_ready_callback(uint32_t pwm_id)    // PWM callback function
{
    ready_flag = true;
}


/**
 * @brief Handler for timer events.
 */
void timer_1_event_handler(nrf_timer_event_t event_type, void* p_context)
{
    static uint32_t i;
    uint32_t led_to_invert = i++;

    switch (event_type)
    {
        case NRF_TIMER_EVENT_COMPARE0:
            
            break;

        default:
            //Do nothing.
            break;
    }
}


void OKIN_dreive_timerInit(void)
{
	uint32_t time_ms = 1; //Time(in miliseconds) between consecutive compare events.
	uint32_t time_ticks;
	uint32_t err_code = NRF_SUCCESS;

	nrf_drv_timer_config_t timer_cfg = NRF_DRV_TIMER_DEFAULT_CONFIG;
	err_code = nrf_drv_timer_init(&TIMER_1, &timer_cfg, timer_1_event_handler);
	APP_ERROR_CHECK(err_code);
	
	time_ticks = nrf_drv_timer_ms_to_ticks(&TIMER_1, time_ms);
	
	nrf_drv_timer_extended_compare(
		 &TIMER_1, NRF_TIMER_CC_CHANNEL0, time_ticks, NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK, true);

    nrf_drv_timer_enable(&TIMER_1);
	
}




void OKIN_drive_PWMInit(void)
{
	ret_code_t err_code;

	/* 2-channel PWM, 200Hz, output on DK LED pins. */
	app_pwm_config_t pwm2_cfg = APP_PWM_DEFAULT_CONFIG_2CH(10870, NRF_VB1_SPEED , NRF_VB2_SPEED);

	/* Switch the polarity of the second channel. */
	pwm2_cfg.pin_polarity[0] = APP_PWM_POLARITY_ACTIVE_HIGH;
	pwm2_cfg.pin_polarity[1] = APP_PWM_POLARITY_ACTIVE_HIGH;
	/* Initialize and enable PWM. */
	err_code = app_pwm_init(&PWM2,&pwm2_cfg,pwm_ready_callback);
	APP_ERROR_CHECK(err_code);
	app_pwm_enable(&PWM2);
	while (app_pwm_channel_duty_set(&PWM2, 0, 0) == NRF_ERROR_BUSY);
	APP_ERROR_CHECK(app_pwm_channel_duty_set(&PWM2, 1, 0));
	
}

void OKIN_drive_PWM_SPEED_Init(void)
{
	ret_code_t err_code;

	/* 2-channel PWM, 200Hz, output on DK LED pins. */
	app_pwm_config_t pwm_cfg = APP_PWM_DEFAULT_CONFIG_2CH(62, NRF_SPEED,UBB_PIN);

	/* Switch the polarity of the second channel. */
	pwm_cfg.pin_polarity[0] = APP_PWM_POLARITY_ACTIVE_LOW;
	pwm_cfg.pin_polarity[1] = APP_PWM_POLARITY_ACTIVE_HIGH;
	/* Initialize and enable PWM. */
	err_code = app_pwm_init(&PWM_SPEED,&pwm_cfg,pwm_ready_callback);
	APP_ERROR_CHECK(err_code);
	app_pwm_enable(&PWM_SPEED);
	while (app_pwm_channel_duty_set(&PWM_SPEED, 0, 0) == NRF_ERROR_BUSY);
	while (app_pwm_channel_duty_set(&PWM_SPEED, 1, 1) == NRF_ERROR_BUSY);
	while (app_pwm_channel_duty_set(&PWM_SPEED, 1, 0) == NRF_ERROR_BUSY);
	//APP_ERROR_CHECK(app_pwm_channel_duty_set(&PWM_SPEED, 1, 0));
}

void OKIN_drive_PWM_UBB_Init(void)
{
	ret_code_t err_code;

	/* 2-channel PWM, 200Hz, output on DK LED pins. */
	app_pwm_config_t pwm_cfg = APP_PWM_DEFAULT_CONFIG_1CH(5000, UBB_PIN);

	/* Switch the polarity of the second channel. */
	pwm_cfg.pin_polarity[0] = APP_PWM_POLARITY_ACTIVE_HIGH;

	/* Initialize and enable PWM. */
	err_code = app_pwm_init(&PWM_UBB,&pwm_cfg,pwm_ready_callback);
	APP_ERROR_CHECK(err_code);
	app_pwm_enable(&PWM_UBB);
	while (app_pwm_channel_duty_set(&PWM_UBB, 0, 0) == NRF_ERROR_BUSY);
	
}



void OKIN_drive_PWM_set( uint16_t value,uint8_t nub)
{
	while (app_pwm_channel_duty_set(&PWM2, nub, value) == NRF_ERROR_BUSY);
}

void OKIN_drive_PWM_SPEED_set( uint16_t value,uint8_t nub)
{
	while (app_pwm_channel_duty_set(&PWM_SPEED, nub, value) == NRF_ERROR_BUSY);
}

void OKIN_drive_UBB_SPEED_set( uint16_t value)
{
	while (app_pwm_channel_duty_set(&PWM_SPEED, 1, 100-value) == NRF_ERROR_BUSY);
}

void OKIN_drive_PWMTest(void)
{
	static uint32_t value;
		
	for (uint8_t i = 0; i < 20; ++i)
	{
			value = (i < 20) ? (i * 5) : (100 - (i - 20) * 5);

			ready_flag = false;
			/* Set the duty cycle - keep trying until PWM is ready... */
			while (app_pwm_channel_duty_set(&PWM2, 0, value) == NRF_ERROR_BUSY);

			/* ... or wait for callback. */
			while (!ready_flag);
			APP_ERROR_CHECK(app_pwm_channel_duty_set(&PWM2, 1, value));
			nrf_delay_ms(25);
	}
}
